package copyengine.network.roomStructure.executeLayer.component
{
	import copyengine.network.roomStructure.CENetworkCommandNotification;
	import copyengine.network.roomStructure.executeLayer.impl.rtmfp.RTMFPExecuteWarp;
	import copyengine.utils.GeneralUtils;
	import copyengine.utils.UUIDFactory;
	import copyengine.utils.debug.CELog;
	import copyengine.utils.tick.GlobalTick;

	import flash.utils.ByteArray;
	import flash.utils.Dictionary;
	import flash.utils.getTimer;

	public final class CENetworkExecuteHandleSubP2PComponent
	{
		private var rtmfpExecuteWarp:RTMFPExecuteWarp;

		//当采用混合方式发送数据时候 会在转发包中给每个转发数据加入UUID
		//因为RTMFP只存在于转发网络环境中(Socket用于和服务器通讯及转发)
		//所以只需要在MIX环境下加入UUID(指定环境的情况下不会出现数据包重复)
		private var fingerprintDic:Dictionary;

		private var isDuringBoosting:Boolean;

		//所有需要用P2P方式发送的ID
		private var allSocketNeighborIDsArray:Array;
		//玩家自己的ID
		private var playerID:String;

		public function CENetworkExecuteHandleSubP2PComponent()
		{
		}

		public function initialize(_rtmfpExecuteWarp:RTMFPExecuteWarp):void
		{
			rtmfpExecuteWarp = _rtmfpExecuteWarp;
		}

		public function dispose():void
		{
			rtmfpExecuteWarp = null;
			fingerprintDic = null;
		}

		public function startP2PBoosting(_groupName:String, _rtmfpURL:String, _allSocketNeighborIDsArray:Array, _playerID:String):void
		{
			//每次Boosting都重新记录发送的包儿
			fingerprintDic = new Dictionary();

			//初始情况下所有人员均为Socket发送状态,在RTMPF连通后
			//才会将可以P2P的发送的ID切换到P2P发送状态
			allSocketNeighborIDsArray = _allSocketNeighborIDsArray;
			playerID = _playerID;
			rtmfpExecuteWarp.connect(_rtmfpURL, _groupName);
		}

		public function endP2PBoosting():void
		{
			rtmfpExecuteWarp.disconnect();
			isDuringBoosting = false;
			fingerprintDic = null;
		}

		/**
		 * 由HandleMediator回调
		 */
		public function onRTMFPServerConnect():void
		{
			isDuringBoosting = true;
			GlobalTick.instance.callLaterAfterTimerCount(onSendRTMFPTestPackage, 3, 3);
		}

		public function onRTMFPServerClosed():void
		{
			isDuringBoosting = false;
		}

		/**
		 * 取得所有需Socket发送的IDArray(游戏玩家可以通过P2P方式发送)
		 */
		public function getAllSocketSendIDs():Array
		{
			return allSocketNeighborIDsArray;
		}


		public function addFingerprintInForwardData(_forwardData:Object):void
		{
			_forwardData["fingerprint"] = UUIDFactory.instance.generateUUID();
		}

		/**
		 *1·当接受到数据后,根据Fingerprint判断,如果当前数据包已经发送过,则不再发送
		 *2·或者当前数据包为RTMFP初始化时候发送的检测数据包,也不在向上发送
		 *3·如果当前数据包的接受者不是玩家,不向上发送
		 *
		 * 不向上发送则返回false,该函数唯仅在初始化时候对数据包有操作,其余时候仅用作判断函数
		 *
		 */
		public function onReceiveData(_command:int, _commandArg:Object = null, _forwardData:Object = null):Boolean
		{
			//收到测试网络环境用的数据包
			if (_command == CENetworkCommandNotification.F_RESERVE_COMMAND_RTMFP_TEST)
			{
				onReceiveRTMFPTestPackage(_commandArg);
				return false
			}
			//判断数据包是否含有指纹,指纹是否被Mark过
			//如果没有被Mark过代表是第一次接收到数据包及可以向上转发
			else
			{
				if (_forwardData)
				{
					var fingerprint:String = _forwardData["fingerprint"];
					if (fingerprintDic[fingerprint])
					{
						return false;
					}
					else
					{
						fingerprintDic[fingerprint] = true;
						return true;
					}
				}
				else
				{
					return true;
				}
			}
		}

		/**
		 * 当前是否使用P2P加速
		 */
		public function isBoosting():Boolean
		{
			return isDuringBoosting;
		}

		//========================
		//===Private Function
		//========================

		private function onSendRTMFPTestPackage():void
		{
			//测试数据包
			var rtmfpTestPackData:Object =
				{
					rtmfpTestMark:true,
					sendTime:getTimer(),
					senderID:playerID
				};
			rtmfpExecuteWarp.sendData(CENetworkCommandNotification.F_RESERVE_COMMAND_RTMFP_TEST, rtmfpTestPackData);
		}

		private function onReceiveRTMFPTestPackage(_package:Object):void
		{
			var senderID:String = _package["senderID"];
			//收到发出去的返回包
			if (senderID == playerID)
			{
				//发送者ID
				var receiverID:String = _package["receiverID"];
				//目前不对P2P的延迟做处理,只要能收到P2P数据及不再使用Socket发送
				var sendTime:int = _package["sendTime"];
				//删除sendTime需要Socket发送的ID,当前用户可以使用P2P通信
				removeIDFromSocketNeighborIDsArray(receiverID);
			}
			//收到别人发来的数据包
			else
			{
				_package["receiverID"] = playerID;
				//表示自己收到数据包,再将包儿发回去
				rtmfpExecuteWarp.sendData(CENetworkCommandNotification.F_RESERVE_COMMAND_RTMFP_TEST, _package);
			}
		}

		private function removeIDFromSocketNeighborIDsArray(_id:String):Boolean
		{
			return GeneralUtils.removeElementFromArrayOrVector(_id, allSocketNeighborIDsArray);
		}

	}
}
